package com.ruoyi.web.controller.api.recipe;

import com.ruoyi.api.domain.recipe.*;
import com.ruoyi.common.annotation.NoLoginRequired;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.recipe.domain.*;
import com.ruoyi.recipe.service.*;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.controller.api.APIController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.Collectors;

@Api("菜品")
@RestController
@RequestMapping("/api/dish")
@NoLoginRequired
public class DishController extends APIController {

    @Autowired
    private IRecipeCategoryService recipeCategoryService;

    @Autowired
    private IRecipeCategoryDishService recipeCategoryDishService;

    @Autowired
    private IRecipeDishService recipeDishService;

    @Autowired
    private IRecipeDishItemService recipeDishItemService;

    @Autowired
    private IRecipeDishStepService recipeDishStepService;

    @Autowired
    private IRecipeDishMealService recipeDishMealService;

    @Autowired
    private IRecipeCollectService recipeCollectService;

    @Autowired
    private IRecipeBrowsingHistoryService recipeBrowsingHistoryService;

    @Autowired
    private ISysUserService sysUserService;

    @ApiOperation("获取菜品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId", value = "分类id", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "keywords", value = "搜索值", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", dataType = "Integer", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", dataType = "Integer", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "isAsc", value = "排序方式（desc或者asc）", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "orderByColumn", value = "排序列", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "openId", value = "微信openId", dataType = "String", dataTypeClass = String.class)
    })
    @PostMapping("/list")
    public TableDataInfo list(@RequestParam(value = "categoryId", required = false, defaultValue = "0") long categoryId, @RequestParam(value = "keywords", required = false, defaultValue = "") String keywords, @RequestParam(value = "openId", required = false, defaultValue = "") String openId) {
        RecipeDish parameterEntity = new RecipeDish();
        if (categoryId > 0) {
            parameterEntity.setCategoryId(categoryId);
        }
        if (!StringUtils.isEmpty(keywords)) {
            parameterEntity.setSearchValue(keywords.trim());
        }
        if (!StringUtils.isEmpty(openId)) {
            parameterEntity.setOpenId(openId.trim());
        }
        parameterEntity.setStatus("0");

        startPage();

        List<RecipeDish> DishList = recipeDishService.selectRandRecipeDish(parameterEntity);
        List<DishEntity> list = new ArrayList<>();
        String baseUrl = getBaseUrl();
        for (RecipeDish recipeDish : DishList) {
            DishEntity dishEntity = new DishEntity();
            BeanUtils.copyBeanProp(dishEntity, recipeDish);
            if (StringUtils.isNotEmpty(recipeDish.getDishPic()) && !StringUtils.ishttp(recipeDish.getDishPic())) {
                String fullDishPic = baseUrl + recipeDish.getDishPic();
                dishEntity.setDishPic(fullDishPic);
            }
            list.add(dishEntity);
        }

        return getDataTable(list);
    }

    @ApiOperation("获取推荐菜品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId", value = "分类id", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "keywords", value = "搜索值", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", dataType = "Integer", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", dataType = "Integer", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "isAsc", value = "排序方式（desc或者asc）", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "orderByColumn", value = "排序列", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "openId", value = "微信openId", dataType = "String", dataTypeClass = String.class)
    })
    @PostMapping("/recommend")
    public TableDataInfo recommend(@RequestParam(value = "categoryId", required = false, defaultValue = "0") long categoryId, @RequestParam(value = "keywords", required = false, defaultValue = "") String keywords, @RequestParam(value = "openId", required = false, defaultValue = "") String openId) {
        RecipeDish parameterEntity = new RecipeDish();
        if (categoryId > 0) {
            parameterEntity.setCategoryId(categoryId);
        }
        if (!StringUtils.isEmpty(keywords)) {
            parameterEntity.setSearchValue(keywords.trim());
        }
        if (!StringUtils.isEmpty(openId)) {
            parameterEntity.setOpenId(openId.trim());
        }
        parameterEntity.setStatus("0");

        startPage();

        List<RecipeDish> DishList = recipeDishService.selectRandRecipeDish(parameterEntity);
        List<DishEntity> list = new ArrayList<>();
        String baseUrl = getBaseUrl();
        for (RecipeDish recipeDish : DishList) {
            DishEntity dishEntity = new DishEntity();
            BeanUtils.copyBeanProp(dishEntity, recipeDish);
            if (StringUtils.isNotEmpty(recipeDish.getDishPic()) && !StringUtils.ishttp(recipeDish.getDishPic())) {
                String fullDishPic = baseUrl + recipeDish.getDishPic();
                dishEntity.setDishPic(fullDishPic);
            }
            list.add(dishEntity);
        }

        return getDataTable(list);
    }

    @ApiOperation("获取菜品详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dishId", value = "菜品Id", required = true, dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "openId", value = "微信openId", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("/detail")
    public AjaxResult getDishDetail(Long dishId, String openId) {
        String baseUrl = getBaseUrl();

        RecipeDish recipeDish = recipeDishService.selectRecipeDishByDishId(dishId);
        if (recipeDish == null) return error("菜品不存在");

        if (StringUtils.isNotEmpty(openId)) {
            RecipeCollect recipeCollect = new RecipeCollect();
            recipeCollect.setDishId(recipeDish.getDishId());
            recipeCollect.setOpenId(openId);
            List<RecipeCollect> collectList = recipeCollectService.selectRecipeCollectList(recipeCollect);
            if (collectList != null && collectList.size() > 0) {
                recipeDish.setIsCollect(true);
            }
        } else {
            recipeDish.setIsCollect(false);
        }

        RecipeDishItem dishItemEntity = new RecipeDishItem();
        dishItemEntity.setDishId(dishId);
        dishItemEntity.setItemType("0");
        dishItemEntity.setStatus("0");
        List<RecipeDishItem> zhuLiaoList = recipeDishItemService.selectRecipeDishItemList(dishItemEntity);

        dishItemEntity.setItemType("1");
        List<RecipeDishItem> fuLiaoList = recipeDishItemService.selectRecipeDishItemList(dishItemEntity);

        RecipeDishStep dishStepEntity = new RecipeDishStep();
        dishStepEntity.setDishId(dishId);
        dishStepEntity.setStatus("0");
        List<RecipeDishStep> stepList = recipeDishStepService.selectRecipeDishStepList(dishStepEntity);
        for (RecipeDishStep step : stepList) {
            if (StringUtils.isNotEmpty(step.getStepPic()) && !StringUtils.ishttp(step.getStepPic())) {
                String fullDishPic = baseUrl + step.getStepPic();
                step.setStepPic(fullDishPic);
            }
        }

        RecipeDishMeal dishMealEntity = new RecipeDishMeal();
        dishMealEntity.setDishId(dishId);
        dishMealEntity.setStatus("0");
        List<RecipeDishMeal> mealList = recipeDishMealService.selectRecipeDishMealList(dishMealEntity);
        List<DishMealEntity> mealEntityList = new ArrayList<>();
        for (RecipeDishMeal meal : mealList) {
            // mealEntityList查找monthAge等于meal.getMonthAge()的记录
            DishMealEntity entity = mealEntityList.stream().filter(e -> e.getMonthAge().equals(meal.getMonthAge())).findFirst().orElse(null);
            if (entity == null) {
                entity = new DishMealEntity();
                BeanUtils.copyBeanProp(entity, meal);
                mealEntityList.add(entity);
            }
            if (entity.getDetailContent() == null) {
                entity.setDetailContent(new ArrayList<>());
            }
            DishMealItemEntity itemEntity = new DishMealItemEntity();
            BeanUtils.copyBeanProp(itemEntity, meal);
            entity.getDetailContent().add(itemEntity);
        }

        DishDetailEntity detailEntity = new DishDetailEntity();
        BeanUtils.copyBeanProp(detailEntity, recipeDish);
        detailEntity.setZhuLiao(zhuLiaoList);
        detailEntity.setFuLiao(fuLiaoList);
        detailEntity.setBuZhou(stepList);
        detailEntity.setFuShi(mealEntityList);

        // 保存浏览历史
        if (StringUtils.isNotEmpty(openId)) {
            SysUser user = sysUserService.selectUserByOpenId(openId);
            if (user != null) {
                RecipeBrowsingHistory recipeHistory = new RecipeBrowsingHistory();
                recipeHistory.setDishId(dishId);
                recipeHistory.setUserId(user.getUserId());
                recipeHistory.setOpenId(openId);
                recipeHistory.setCreateTime(new Date());
                recipeBrowsingHistoryService.insertRecipeBrowsingHistory(recipeHistory);
            }
        }

        return AjaxResult.success(detailEntity);
    }

    @ApiOperation("获取某个菜品信息")
    @ApiImplicitParam(name = "dishId", value = "菜品Id", required = true, dataType = "Long", dataTypeClass = Long.class)
    @GetMapping("/get")
    public AjaxResult getDish(Long dishId) {
        if (dishId < 1) return error("菜品Id不合法");

        RecipeDish recipeDish = recipeDishService.selectRecipeDishByDishId(dishId);
        if (recipeDish == null) return error("菜品不存在");

        return AjaxResult.success(recipeDish);
    }

    @ApiOperation("获取转盘的菜品数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageSize", value = "查询记录条数，默认10", dataType = "Integer", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "category_id", value = "类别id", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "keywords", value = "搜索值", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("/wheel")
    public AjaxResult getWheelData(@RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
                                   @RequestParam(value = "category_id", required = false, defaultValue = "0") long category_id,
                                   @RequestParam(value = "keywords", required = false, defaultValue = "") String keywords) {
        if (pageSize < 1) pageSize = 10;

        RecipeDish recipeDish = new RecipeDish();
        recipeDish.setLimit(pageSize);
        recipeDish.setStatus("0");
        if (category_id > 0) {
            recipeDish.setCategoryId(category_id);
        }
        if (!StringUtils.isEmpty(keywords)) {
            recipeDish.setSearchValue(keywords.trim());
        }
        List<RecipeDish> list = recipeDishService.selectRandRecipeDish(recipeDish);

        //将list转换为DishWheelEntity
        List<DishWheelEntity> wheelList = list.stream().map(item -> {
            DishWheelEntity entity = new DishWheelEntity();
            entity.setDishId(item.getDishId());
            entity.setDishName(item.getDishName());
            return entity;
        }).collect(Collectors.toList());

        return AjaxResult.success(wheelList);
    }

    @ApiOperation("导入Json数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "list", value = "json数据", dataType = "java.util.List", dataTypeClass = java.util.List.class),
    })
    @PostMapping("/import")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importData(@RequestBody List<DishImportEntity> list) throws Exception {
        if (StringUtils.isNull(list) || list.size() == 0) {
            throw new Exception("导入的数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        List<RecipeDish> dishList = new ArrayList<>();
        List<RecipeCategoryDish> categoryDishList = new ArrayList<>();
        List<RecipeDishItem> dishItemList = new ArrayList<>();
        List<RecipeDishStep> dishStepList = new ArrayList<>();
        List<RecipeDishMeal> dishMealList = new ArrayList<>();
        List<RecipeCategory> categoryList = new ArrayList<>();

        List<RecipeCategory> categoryTmpList = recipeCategoryService.selectCategoryAll();
        // 通过categoryTmpList获取最大的categorySort
        int maxCategorySort = 1;
        if (categoryTmpList != null && categoryTmpList.size() > 0) {
            for (RecipeCategory category : categoryTmpList) {
                if (category.getCategorySort() > maxCategorySort) {
                    maxCategorySort = category.getCategorySort();
                }
            }
        }
        // categoryName categoryId键值对
        Map<String, Long> categoryTmpMap = new HashMap<>();
        for (RecipeCategory category : categoryTmpList) {
            categoryTmpMap.put(category.getCategoryName(), category.getCategoryId());
        }

        // 处理食谱类别
        for (DishImportEntity item : list) {
            List<String> dishTitleList = item.getDishTitleList();
            if (dishTitleList != null && dishTitleList.size() > 0) {
                for (String dishTitle : dishTitleList) {
                    if (StringUtils.isEmpty(dishTitle)) continue;

                    if (StringUtils.isNull(categoryTmpMap.get(dishTitle.trim()))) {
                        RecipeCategory category = new RecipeCategory();
                        category.setCategoryName(dishTitle.trim());
                        category.setCategorySort(++maxCategorySort);
                        category.setVisible("1");
                        category.setStatus("0");
                        categoryList.add(category);

                        categoryTmpMap.put(category.getCategoryName(), (long) -1);
                    }
                }
            }
        }
        if (categoryList.size() > 0) {
            int rt = recipeCategoryService.batchInsertCategory(categoryList);
            if (rt < categoryList.size()) {
                throw new Exception("很抱歉，导入失败：食谱类别保存失败！");
            }
            successMsg.append("成功导入食谱类别数据 " + categoryList.size() + " 条！");
        }

        // 开始处理菜品
        List<RecipeCategory> categoryFullList = recipeCategoryService.selectCategoryAll();
        // categoryName categoryId键值对
        Map<String, Long> categoryMap = new HashMap<>();
        for (RecipeCategory category : categoryFullList) {
            categoryMap.put(category.getCategoryName(), category.getCategoryId());
        }

        int maxDishSort = recipeDishService.selectMaxDishSort(new RecipeDish());
        if (maxDishSort < 1) maxDishSort = 1;
        Iterator<DishImportEntity> iterator = list.iterator();
        while (iterator.hasNext()) {
            DishImportEntity item = iterator.next();

            if (failureNum >= 10) {
                break;
            }

            //处理菜品
            if (StringUtils.isEmpty(item.getDishCode())) {
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、" + item.getDishName() + " 导入失败：" + "菜品编码为空");
            }
            item.setDishSort(++maxDishSort);
            //item.setCategoryName(item.getCategoryId().toString());
            item.setCreateTime(DateUtils.getNowDate());
            item.setUpdateTime(DateUtils.getNowDate());
            item.setStatus("0");

            RecipeDish dish = new RecipeDish();
            BeanUtils.copyBeanProp(dish, item);
            dishList.add(dish);

            //处理菜品和类别关系
            List<String> dishTitleList = item.getDishTitleList();
            if (dishTitleList != null && dishTitleList.size() > 0) {
                dish.setDishTitle(StringUtils.join(dishTitleList, ","));

                for (String dishTitle : dishTitleList) {
                    if (StringUtils.isEmpty(dishTitle)) continue;

                    if (StringUtils.isNull(categoryMap.get(dishTitle))) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、" + item.getDishName() + " 导入失败：" + "类别 " + dishTitle + " 不存在");

                        continue;
                    }
                    RecipeCategoryDish categoryDish = new RecipeCategoryDish();
                    categoryDish.setCategoryId(categoryMap.get(dishTitle));
                    categoryDish.setDishName(item.getDishCode());
                    categoryDishList.add(categoryDish);
                }
            }

            if (failureNum > 0) {
                failureMsg.insert(0, "很抱歉，导入失败！请修改文件后重试：");
                throw new Exception(failureMsg.toString());
            }

            //处理菜品材料
            int itemSort = 1;
            if (item.getZhuLiao() != null && item.getZhuLiao().size() > 0) {
                for (RecipeDishItem item1 : item.getZhuLiao()) {
                    //item1.setDishId(dish.getDishId());
                    item1.setDishName(item.getDishCode());
                    item1.setItemSort(itemSort++);
                    item1.setItemType("0");
                    item1.setStatus("0");
                    dishItemList.add(item1);
                }
            }
            if (item.getFuLiao() != null && item.getFuLiao().size() > 0) {
                for (RecipeDishItem item1 : item.getFuLiao()) {
                    //item1.setDishId(dish.getDishId());
                    item1.setDishName(item.getDishCode());
                    item1.setItemSort(itemSort++);
                    item1.setItemType("1");
                    item1.setStatus("0");
                    dishItemList.add(item1);
                }
            }

            //处理菜品步骤
            if (item.getBuZhou() != null && item.getBuZhou().size() > 0) {
                for (RecipeDishStep step : item.getBuZhou()) {
                    //step.setDishId(dish.getDishId());
                    step.setDishName(item.getDishCode());
                    step.setStatus("0");
                    dishStepList.add(step);
                }

                //如果菜品图片为空，取步骤的最后一张图片
                if (StringUtils.isEmpty(item.getDishPic())) {
                    RecipeDishStep step = item.getBuZhou().get(item.getBuZhou().size() - 1);
                    if (StringUtils.isNotEmpty(step.getStepPic())) {
                        item.setDishPic(step.getStepPic());
                    }
                }
            }

            //处理婴儿辅食
            if (item.getFuShi() != null && item.getFuShi().size() > 0) {
                for (DishMealEntity dishMealEntity : item.getFuShi()) {
                    long mealSort = 1;
                    for (DishMealItemEntity dishMealItemEntity : dishMealEntity.getDetailContent()) {
                        RecipeDishMeal recipeDishMeal = new RecipeDishMeal();
                        recipeDishMeal.setDishName(item.getDishCode());
                        recipeDishMeal.setMonthAge(dishMealEntity.getMonthAge());
                        recipeDishMeal.setMealTitle(dishMealItemEntity.getMealTitle());
                        recipeDishMeal.setMealName(dishMealItemEntity.getMealName());
                        recipeDishMeal.setMealSort(mealSort++);
                        recipeDishMeal.setStatus("0");
                        dishMealList.add(recipeDishMeal);
                    }
                }
            }
        }

        if (dishList.size() == 0) {
            failureMsg.insert(0, "很抱歉，导入失败！菜品不能为空：");
            throw new Exception(failureMsg.toString());
        }

        int rows = recipeDishService.batchInsertRecipeDish(dishList);
        if (rows < dishList.size()) {
            failureMsg.insert(0, "很抱歉，导入失败：菜品保存失败！");
            throw new Exception(failureMsg.toString());
        }
        successMsg.append("成功导入菜品数据 " + dishList.size() + " 条！");

        //查询菜品
        List<RecipeDish> dishInDBList = recipeDishService.selectRecipeDishList(new RecipeDish());
        Map<String, Long> dishMap = new HashMap<>();
        for (RecipeDish dish : dishInDBList) {
            dishMap.put(dish.getDishCode(), dish.getDishId());
        }

        //保存菜品和类别的关系
        if (categoryDishList.size() > 0) {
            for (RecipeCategoryDish item : categoryDishList) {
                item.setDishId(dishMap.get(item.getDishName()));
            }
            rows = recipeCategoryDishService.batchInsertRecipeCategoryDish(categoryDishList);
            if (rows <= 0) {
                failureMsg.insert(0, "很抱歉，导入失败：菜品和类型的关系保存失败！");
                throw new Exception(failureMsg.toString());
            }
            successMsg.append("成功导入菜品和类型的关系数据 " + categoryDishList.size() + " 条！");
        }

        //保存材料
        if (dishItemList.size() > 0) {
            for (RecipeDishItem item : dishItemList) {
                item.setDishId(dishMap.get(item.getDishName()));
            }
            rows = recipeDishItemService.batchInsertRecipeDishItem(dishItemList);
            if (rows <= 0) {
                failureMsg.insert(0, "很抱歉，导入失败：菜品材料保存失败！");
                throw new Exception(failureMsg.toString());
            }
            successMsg.append("成功导入菜品材料数据 " + dishItemList.size() + " 条！");
        }

        //保存步骤
        if (dishStepList.size() > 0) {
            for (RecipeDishStep item : dishStepList) {
                item.setDishId(dishMap.get(item.getDishName()));
            }
            rows = recipeDishStepService.batchInsertRecipeDishStep(dishStepList);
            if (rows <= 0) {
                failureMsg.insert(0, "很抱歉，导入失败：菜品步骤保存失败！");
                throw new Exception(failureMsg.toString());
            }
            successMsg.append("成功导入菜品步骤数据 " + dishStepList.size() + " 条！");
        }

        //保存婴儿辅食
        if (dishMealList.size() > 0) {
            for (RecipeDishMeal item : dishMealList) {
                item.setDishId(dishMap.get(item.getDishName()));
            }
            rows = recipeDishMealService.batchInsertRecipeDishMeal(dishMealList);
            if (rows <= 0) {
                failureMsg.insert(0, "很抱歉，导入失败：婴儿辅食保存失败！");
                throw new Exception(failureMsg.toString());
            }
            successMsg.append("成功导入婴儿辅食数据 " + dishMealList.size() + " 条！");
        }

        return AjaxResult.success(successMsg.toString());
    }
}
